using System;
using System.Collections.Generic;
using System.IO;


namespace Development.Tools
{
    public class DataForm<T> : DataFormBase where T : BaseData
	{

        public T[] Datas;
		
		private SortedDictionary<int, T> mSheet;
		
		private void Initialize ()
		{
			mSheet = new SortedDictionary<int, T>();
			for (int i = 0; i < Datas.Length; ++i)
			{
                if (!mSheet.ContainsKey(Datas[i].ID))
                    mSheet.Add(Datas[i].ID, Datas[i]);
                else
                {
                }
					
			}
		}
		
		public T this[int ID] {
			get {
				T val;
				bool ret = mSheet.TryGetValue(ID, out val);
				return ret ? val : null;
			}
		}

        public override object GetData(int ID)
        {
            T val;
            bool ret = mSheet.TryGetValue(ID, out val);
            return ret ? val : null;
        }
		
		public T Get (int ID)
		{
			T val;
			bool ret = mSheet.TryGetValue(ID, out val);
			return ret ? val : null;
		}
		
		public bool TryGetValue (int key, out T val)
		{
			return mSheet.TryGetValue(key, out val);
		}

        public override bool Load(string fileName)
        {
            if (!Directory.Exists("tables"))
            {
                Directory.CreateDirectory("tables");
            }

            if (File.Exists("tables\\" + fileName))
            {
                byte[] fileText = File.ReadAllBytes("tables\\" + fileName);
                try
                {
                    ReadXml(fileText);
                }
                catch(Exception e)
                {
                    Log.WriteLog(ELogLevel.LOG_ERROR, e.Message +"  "+ fileName);
                    return false;
                }
         
            }
            else
            {
                return WriteXml(fileName);
            }
            return true;
        }

        protected bool WriteXml(string fileName)
        {
            SortedDictionary<int, BaseData> dict = new SortedDictionary<int, BaseData>();

            Type tableType = typeof(BaseData);
            Type type = typeof(T);
            if (!tableType.IsAssignableFrom(type))
            {
                Log.WriteLog(ELogLevel.LOG_ERROR, "is not assignable basedata");
                return false;
            }

            for (int i = 0; i < 2; ++i)
            {
                BaseData data = System.Activator.CreateInstance(type) as BaseData;
                data.ExportDefaultProperties();
                data.ID = i + 1;
                dict.Add(i, data);
            }

            DataTool.WriteXml(dict, type, "tables\\", fileName);
            return true;
        }
		

		protected void ReadXml (byte [] fileBytes)
		{
            MemoryStream stream = new MemoryStream(fileBytes);
			mSheet = DataTool.ReadXml<T>(stream);
			Datas = new T[mSheet.Values.Count];
			mSheet.Values.CopyTo(Datas, 0);

            Initialize();
		}

        public override S[] GetTable<S>()
        {
            return Datas as S[];
        }

	}
}